//ECE 454 Spring 2008 Assignment 1
//Macaranas, Joseph jjmacara
//Turner, Travis t2turner

//
// File RPCheader.h
//
// This file defines various constants that are common between client and server
//

#ifndef __RPC_H__
#define __RPC_H__

//LIBRARIES
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

// Argument Types

#define ARG_CHAR         1
#define ARG_SHORT        2
#define ARG_INT          3
#define ARG_LONG         4
#define ARG_FLOAT        5
#define ARG_DOUBLE       6
#define ARG_STRING       7

#define ARG_INPUT       31
#define ARG_OUTPUT      30

#define TERMINATE 		't'
#define REGISTER		'r'
#define REQUEST			'q'

#define RESULT_SUCCESS 	0
#define RESULT_FAILURE	-1
#define RESULT_WARNING	1

//specific warnings/errors (return values)
#define NO_BINDER			-10
#define INVALID_HOST		-9
#define SOCKET_FAILURE		-8
#define SEND_ERROR			-7
#define RECV_ERROR			-6
#define NO_SERVER_IMPL		-11
#define ALL_SERV_FAIL		-5

//for requestType usage in the binder_msg struct below
#define SERVER_REGISTER		1
#define CLIENT_LOOKUP		2
#define SERVER_DEREGISTER	3
#define TERMINATOR			4
#define REQUEST_SUCCESS		0 //used to notify requestor during response
#define REQUEST_WARNING		6 //used to notify requestor during response
#define REQUEST_ERROR		-1 //used to notify requestor during response

#define PORT 1337

#define MAX_LENGTH		2048

//typedefs

typedef int (*function)(int *, void **);

// Client Stub Functions

int rpcCall(char *name, int *argTypes, void **args);
int rpcTerminate(void);

// Server Stub Functions

int rpcRegister(char *name, int *argTypes, function f);
int rpcExecute( void );

using namespace std;



// Yuck, those are ugly, and we'd have to do things
// like (ARG_CHAR << 16) | (1 << ARG_INPUT), which
// is totally unreadable in code.  So, let's fix that
// as follows:

const unsigned int typeShift = 16;
const unsigned int rpcChar   = ARG_CHAR   << typeShift;
const unsigned int rpcShort  = ARG_SHORT  << typeShift;
const unsigned int rpcInt    = ARG_INT    << typeShift;
const unsigned int rpcLong   = ARG_LONG   << typeShift;
const unsigned int rpcFloat  = ARG_FLOAT  << typeShift;
const unsigned int rpcDouble = ARG_DOUBLE << typeShift;
const unsigned int rpcString = ARG_STRING << typeShift;

const unsigned int rpcInput  = 1 << ARG_INPUT;
const unsigned int rpcOutput = 1 << ARG_OUTPUT;

// Let us define bit 29 of the argTypes as
// rpcPartialMatch.  If this bit is not
// set, then the interface will match the
// assignment specification.  If this bit is
// set, the binder will not match that argument
// type.  This allows us to have a very
// useful test case (shown in sampleClient.C)
// called displayParms().

const unsigned int rpcPartialMatch = (1 << 29);

// Let's just arbitrarily set it to 255 for convenience.
const int PARAMETER_COUNT = 255;

#endif



